package com.powernode.service.impl;

import com.powernode.feign.RemoteUserService;
import com.powernode.config.WxPayV3Properties;
import com.powernode.domain.CreateWxPaymentForm;
import com.powernode.domain.Member;
import com.powernode.domain.PaymentInfo;
import com.powernode.domain.WxPrepayVo;
import com.powernode.model.Result;
import com.powernode.service.IWxPayService;
import com.powernode.service.PaymentService;
import com.powernode.utils.RequestUtils;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.core.notification.NotificationParser;
import com.wechat.pay.java.core.notification.RequestParam;
import com.wechat.pay.java.service.payments.jsapi.JsapiServiceExtension;
import com.wechat.pay.java.service.payments.jsapi.model.*;
import com.wechat.pay.java.service.payments.model.Transaction;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;

@Service
public class WxPayServiceImpl implements IWxPayService {

    @Autowired
    private PaymentService paymentService;

    @Autowired
    private RSAAutoCertificateConfig rsaAutoCertificateConfig;

    @Autowired
    private WxPayV3Properties wxPayV3Properties;

    @Autowired
    private RemoteUserService remoteUserService;

    @Override
    public WxPrepayVo createWxPayment(CreateWxPaymentForm createWxPaymentForm) {
        // 1.添加微信支付记录（状态：未支付）  payment_info
        PaymentInfo paymentInfo = paymentService.savePaymentInfo(createWxPaymentForm.getOrderNumber());

        // 2.创建微信封装对象 JsapiServiceExtension
        JsapiServiceExtension service = new JsapiServiceExtension.Builder().config(rsaAutoCertificateConfig).build();

        // 3.封装这个对象需要相关参数
        PrepayRequest request = new PrepayRequest();
        Amount amount = new Amount();
        //amount.setTotal(paymentInfo.getAmount().multiply(new BigDecimal(100)).intValue());
        // 测试数据
        amount.setTotal(1);
        request.setAmount(amount);

        request.setAppid(wxPayV3Properties.getAppid());
        request.setMchid(wxPayV3Properties.getMerchantId());
        request.setDescription(paymentInfo.getContent());
        request.setNotifyUrl(wxPayV3Properties.getNotifyUrl());
        request.setOutTradeNo(paymentInfo.getOrderNo());

        // 获取用户信息
        Payer payer = new Payer();
        // 远程调用
        Result<Member> userInfoR = remoteUserService.getMemberInfo(paymentInfo.getUserId());
        Member userInfo = userInfoR.getData();
        if(userInfo == null) {
            throw new RuntimeException("用户不存在");
        }
        String openid = userInfo.getOpenId();
        payer.setOpenid(openid);
        request.setPayer(payer);

        try {
            // 4.调用第二步创建对象里面的方法，发起微信支付
            PrepayWithRequestPaymentResponse response = service.prepayWithRequestPayment(request);

            // 5.按照要求返回需要数据WxPrepayVo
            WxPrepayVo wxPrepayVo = new WxPrepayVo();
            BeanUtils.copyProperties(response, wxPrepayVo);
            wxPrepayVo.setTimestamp(response.getTimeStamp());

            return wxPrepayVo;
        } catch (Exception e) {
            // 处理订单已支付的情况
            if (e.getMessage() != null && e.getMessage().contains("ORDERPAID")) {
                // 查询订单支付状态
                Transaction transaction = queryPayStatus(paymentInfo.getOrderNo());
                if (transaction != null && transaction.getTradeState() == Transaction.TradeStateEnum.SUCCESS) {
                    // 更新支付状态
                    paymentService.updatePaymentStatus(transaction);
                    // 方案1：返回一个空的预支付对象，表示支付已完成
                    WxPrepayVo wxPrepayVo = new WxPrepayVo();
                    wxPrepayVo.setOrderNo(paymentInfo.getOrderNo());
                    wxPrepayVo.setPayStatus("SUCCESS");
                    return wxPrepayVo;
                    // 方案2：直接抛出异常，让前端知道订单已支付
                    /*throw new RuntimeException("订单已支付");*/
                }
            }
            throw e;
        }
    }

    @Override
    public void wxnotify(HttpServletRequest request) {
        String wechatPaySerial = request.getHeader("Wechatpay-Serial");
        String nonce = request.getHeader("Wechatpay-Nonce");
        String timestamp = request.getHeader("Wechatpay-Timestamp");
        String signature = request.getHeader("Wechatpay-Signature");
        String requestBody = RequestUtils.readData(request);

        // 2.构造 RequestParam
        RequestParam requestparam = new RequestParam.Builder()
                .serialNumber(wechatPaySerial)
                .nonce(nonce)
                .signature(signature)
                .timestamp(timestamp)
                .body(requestBody)
                .build();

        // 3.初始化 NotificationParser
        NotificationParser parser = new NotificationParser(rsaAutoCertificateConfig);
        // 4.已支付通知回调为例，验签、解密并转换成 Transaction
        Transaction transaction = parser.parse(requestparam, Transaction.class);
        if (null != transaction && transaction.getTradeState() == Transaction.TradeStateEnum.SUCCESS) {
            // 5.处理支付业务
            paymentService.updatePaymentStatus(transaction);
        }
    }

    // 根据订单号调用微信服务接口，查询支付相关状态信息
    @Override
    public Transaction queryPayStatus(String orderNumber) {
        JsapiServiceExtension service = new JsapiServiceExtension.Builder().config(rsaAutoCertificateConfig).build();
        QueryOrderByOutTradeNoRequest queryRequest = new QueryOrderByOutTradeNoRequest();
        queryRequest.setMchid(wxPayV3Properties.getMerchantId());
        queryRequest.setOutTradeNo(orderNumber);
        Transaction transaction = service.queryOrderByOutTradeNo(queryRequest);
        return transaction;
    }
}
